home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
asm
/
alib11b.zip
/
CODE1.ZIP
/
DISKINFO
/
FDUMP.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-10-04
|
9KB
|
338 lines
title 'DUMP --- Display File Contents'
; DUMP --- a utility to display the contents of a file in hex
; and ASCII format. Requires PC-DOS 2.0 or MS-DOS 2.0.
; Used in the form:
; A>dump path\filename.ext [ >device ]
; (item in square brackets is optional)
; version 1.0 March 25, 1984
; Copyright (c) 1984 by Ray Duncan
; May be freely reproduced for non-commercial use.
cr equ 0dh ;ASCII carriage return
lf equ 0ah ;ASCII line feed
blank equ 20h ;ASCII space code
command equ 80h ;buffer for command tail
blksize equ 128 ;size of input file records
output_handle equ 1 ;handle of standard output device
;(can be redirected)
error_handle equ 2 ;handle of standard error device
;(not redirectable)
cseg segment para public 'CODE'
assume cs:cseg,ds:data,es:data,ss:stack
dump proc far ;entry point from PC-DOS
push ds ;save DS:0000 for final
xor ax,ax ;return to PC-DOS
push ax
mov ax,data ;make our data segment
mov es,ax ;addressable via ES register.
mov ah,30h ;check version of PC-DOS.
int 21h
cmp al,2
jae dump1 ;proceed, DOS 2.0 or greater.
mov dx,offset msg3 ;DOS 1.x --- print error message;
mov ax,es ;we must use the old PC-DOS
mov ds,ax ;string output function since
mov ah,9 ;handles are not available in
int 21h ;this version of PC-DOS.
ret
dump1: call get_filename ;get path and file spec. for
;input file from command line tail.
mov ax,es ;set DS=ES for remainder
mov ds,ax ;of program.
jnc dump2 ;jump, got acceptable name.
mov dx,offset msg2 ;missing or illegal filespec,
mov cx,msg2_length
jmp dump9 ;print error message and exit.
dump2: call open_input ;now try to open input file
jnc dump3 ;jump,opened input ok
mov dx,offset msg1 ;open of input file failed,
mov cx,msg1_length
jmp dump9 ;print error msg and exit.
dump3: call read_block ;initialize input file buffer
jnc dump4 ;jump,got a block
mov dx,offset msg4 ;empty file,print error
mov cx,msg4_length
jmp dump9 ;message and exit
;file successfully opened,
dump4: ;now convert and display it!
call get_char ;read 1 character from input.
jc dump8 ;jump, end of file
inc input_addr ;update relative file position
or bx,bx ;is this 1st char of block?
jnz dump5 ;no
call print_heading
dump5: and bx,0fh ;is this first byte of 16?
jnz dump6 ;no,jump
push ax ;save the byte
mov di,offset output;convert relative file addr.
mov ax,input_addr ;for output string
call conv_word
pop ax
dump6: ;store ASCII version of character,
;if it is alphanumeric,
mov di,offset outputb
add di,bx ;calculate output string address
mov byte ptr [di],'.' ;if it is control character,
cmp al,blank ;just print a dot.
jb dump7 ;jump, not alphanumeric.
cmp al,7eh
ja dump7 ;jump, not alphanumeric.
mov [di],al ;store ASCII character.
dump7: ;now convert binary byte
;to hex ASCII equivalent.
push bx ;save offset 0-15 of this byte.
;calc. its position in
;output string.
mov di,offset outputa
add di,bx ;base addr + (offset*3)
add di,bx
add di,bx
call conv_byte ;convert data byte to hex
pop bx ;restore byte offset
cmp bx,0fh ;16 bytes converted yet?
jne dump4 ;no,get another byte
mov dx,offset output
mov cx,output_length
call write_std ;yes, print the line
jmp dump4 ;get next char. from input file.
dump8: ;end of file detected,
call close_input ;close input file.
ret ;now return to PC-DOS.
dump9: ;come here to print message
;on standard error device,
call write_error ;and return control to PC-DOS
ret
dump endp
get_filename proc near ;process name of input file
;return Carry = 0 if successful
;return Carry = 1 if no filename
;DS:SI <- addr command line
mov si,offset command
;ES:DI <- addr filespec buffer
mov di,offset input_name
cld
lodsb ;any command line present?
or al,al ;return error status if not.
jz get_filename4
get_filename1: ;scan over leading blanks
lodsb ;to file name.
cmp al,cr ;if we hit carriage return...
je get_filename4 ;jump, name is missing
cmp al,20h ;is this a blank?
jz get_filename1 ;if so keep scanning.
get_filename2: ;found first char of name,
stosb ;move last char. to output
;file name buffer.
lodsb ;check next character, found
cmp al,cr ;carriage return yet?
je get_filename3 ;yes,exit with success code.
cmp al,20h ;is this a blank?
jne get_filename2 ;if not keep moving chars.
get_filename3: ;exit with carry =0
clc ;for success flag
ret
get_filename4: ;exit with carry =1
stc ;for error flag
ret
get_filename endp
open_input proc near ;open input file
;DS:DX=addr filename
mov dx,offset input_name
mov al,0 ;AL=0 for read only
mov ah,3dh ;function 3dh=open
int 21h ;handle returned in AX,
mov input_handle,ax ;save it for later.
ret ;CY is set if error
open_input endp
close_input proc near ;close input file
mov bx,input_handle ;BX=handle
mov ah,3eh
int 21h
ret
close_input endp
get_char proc near ;get one character from input buffer
;return AL = char, BX = buffer offset
;return CY flag = 1 if end of file
mov bx,input_ptr ;is pointer at end of buffer?
cmp bx,blksize
jne get_char1 ;no,jump
;yes, buffer is exhausted,
mov input_ptr,0
call read_block ;new block must be read from disk.
jnc get_char ;got block, start routine over.
ret ;end of file detected
;so return CY flag = True.
get_char1: ;get data byte into AL,
mov al,[input_buffer+bx]
inc input_ptr ;bump input buffer pointer.
clc ;return CY flag =0 since
ret ;not end of file.
get_char endp
read_block proc near ;read block of data from input file.
;return CY flag = 0 if read ok.
; CY flag = 1 if end of file.
mov bx,input_handle ;request read from PC-DOS.
mov cx,blksize
mov dx,offset input_buffer
mov ah,3fh
int 21h
;initialize pointers
inc input_block
mov input_ptr,0
or ax,ax ;was anything read in? (the OR
; incidentally turns off the CY flag)
jnz read_block1 ;yes,jump
stc ;no,end of file so return CY=True
read_block1:
ret
read_block endp
write_std proc near ;write string to standard output.
;call DX = addr of output string
; CX = length of string
mov bx,output_handle;BX=handle for standard list device.
mov ah,40h ;function 40h=write to device.
int 21h ;request service from DOS.
ret
write_std endp
write_error proc near ;write string to standard error device.
;call DX = addr of output string
; CX = length of string
mov bx,error_handle ;BX=handle for standard error device.
mov ah,40h ;function 40h=write to device.
int 21h ;request service from DOS.
ret
write_error endp
print_heading proc near ;print record number and heading
push ax ;for a block of data
push bx ;first save registers
mov di,offset headinga
mov ax,input_block
call conv_word ;convert record number to ASCII
mov dx,offset heading
mov cx,heading_length
call write_std ;now print heading
pop bx ;restore registers
pop ax
ret ;and exit
print_heading endp
conv_word proc near ;convert 16-bit binary word
; to hex ASCII
;call with AX=binary value
; DI=addr to store string
;returns AX, DI, CX destroyed
push ax
mov al,ah
call conv_byte ;convert upper byte
pop ax
call conv_byte ;convert lower byte
ret
conv_word endp
conv_byte proc near ;convert binary byte to hex ASCII
;call with AL=binary value
; DI=addr to store string
;returns AX, DI, CX modified
sub ah,ah ;clear upper byte
mov cl,16
div cl ;divide binary data by 16
call ascii ;the quotient becomes the first
stosb ;ASCII character
mov al,ah
call ascii ;the remainder becomes the
stosb ;second ASCII character
ret
conv_byte endp
ascii proc near ;convert bottom 4 bits in AL
add al,'0' ;into the hex ASCII character
cmp al,'9'
jle ascii2 ;jump if in range 0-9,
add al,'A'-'9'-1 ;offset it to range A-F,
ascii2: ret ;return ASCII char. in AL.
ascii endp
cseg ends
data segment para public 'DATA'
input_name db 64 dup (0) ;buffer for input filespec
input_handle dw 0 ;token from PCDOS for input file.
input_ptr dw 0 ;pointer to input deblocking buffer
input_addr dw -1 ;relative address in file
input_block dw 0 ;current 128 byte block number
output db 'nnnn',blank,blank
outputa db 16 dup ('00',blank)
db blank
outputb db '0123456789ABCDEF',cr,lf
output_length equ $-output
heading db cr,lf,'Record',blank
headinga db 'nnnn',blank,blank,cr,lf
db 7 dup (blank)
db '0 1 2 3 4 5 6 7 '
db '8 9 A B C D E F',cr,lf
heading_length equ $-heading
input_buffer db blksize dup (?) ;deblocking buffer for input file
msg1 db cr,lf
db 'Cannot find input file.'
db cr,lf
msg1_length equ $-msg1
msg2 db cr,lf
db 'Missing file name.'
db cr,lf
msg2_length equ $-msg2
msg3 db cr,lf
db 'Requires PC-DOS version 2 or greater.'
db cr,lf,'$'
msg4 db cr,lf,'Empty file.',cr,lf
msg4_length equ $-msg4
data ends
stack segment para stack 'STACK'
db 64 dup (?)
stack ends
end dump